/*
 *   AviTab - Aviator's Virtual Tablet
 *   Copyright (C) 2018 Folke Will <folko@solhost.org>
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
#ifndef SRC_LIBNAVIGRAPH_APICALL_H_
#define SRC_LIBNAVIGRAPH_APICALL_H_

#include <functional>
#include <future>
#include <stdexcept>

namespace navigraph {

struct BaseCall {
    virtual void exec() = 0;
    virtual ~BaseCall() = default;
};

template <typename Result>
class APICall: public BaseCall {
public:
    using RunCB = std::function<Result()>;
    using ThenCB = std::function<void(std::future<Result> result)>;

    APICall(RunCB run) {
        runCb = run;
    }

    void andThen(ThenCB then) {
        thenCb = then;
    }

    void exec() override {
        try {
            promise.set_value(runCb());
        } catch (const std::exception &e) {
            promise.set_exception(std::current_exception());
        }
        if (thenCb) {
            thenCb(promise.get_future());
        }
    }

private:
    std::promise<Result> promise;

    RunCB runCb;
    ThenCB thenCb;
};

} /* namespace navigraph */

#endif /* SRC_LIBNAVIGRAPH_APICALL_H_ */
